﻿using HDS.Admin.Api.ViewModels.Booking;
using HDS.Common.Helper;
using HDS.IService.HotelApi;
using HDS.IService.Log;
using HDS.IService.Master;
using HDS.Model;
using HDS.Model.Entity.Log;
using HDS.Model.Entity.Master;
using HDS.SupplierApi.Core.Entity;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace HDS.Admin.Api.Controllers
{
    [Route("[controller]/[action]")]
    [ApiController]
    [EnableCors]
    public class BookingController : AdminController
    {
        private readonly ILogger<BookingController> _ILogger;
        private readonly IHttpClientFactory _IHttpClientFactory;
        private readonly IApiLogService _IApiLogService;
        private readonly IDataCacheService _IDataCacheService;
        private readonly IHotelApiService _IHotelApiService;
        private readonly ISupplierHotelService _ISupplierHotelService;
        private readonly IOrderHotelService _IOrderHotelService;
        private readonly IHotelService _IHotelService;
        private readonly IUpdateLogService _IUpdateLogService;

        public BookingController(IHttpClientFactory clientFactory, ILogger<BookingController> ilogger, IApiLogService iapiLogService, IDataCacheService idataCacheService, IHotelApiService ihotelApiService, ISupplierHotelService isupplierHotelService, IOrderHotelService iorderHotelService, IHotelService ihotelService, IUpdateLogService iupdateLogService)
        {
            _IHttpClientFactory = clientFactory;
            _ILogger = ilogger;
            _IApiLogService = iapiLogService;
            _IDataCacheService = idataCacheService;
            _IHotelApiService = ihotelApiService;
            _ISupplierHotelService = isupplierHotelService;
            _IOrderHotelService = iorderHotelService;
            _IHotelService = ihotelService;
            _IUpdateLogService = iupdateLogService;
        }

        public async Task<ResultData<List<DistributorRate>>> SearchRate([FromBody] SearchRateDto entity)
        {
           var resultData = await _IHotelApiService.SearchRate(entity.Distributor, entity.HotelId, entity.CheckinDate.Date, entity.CheckoutDate.Date, entity.RoomGuest, entity.CurrencyCode, Guid.NewGuid().ToString(), 60 * 1000);

            if (entity.AddRoom && !resultData.Data.IsEmpty())
            {
               await _ISupplierHotelService.AddRooms(resultData.Data.Select(e => e.SupplierRate).ToList());
            }

            return resultData;
        }

        public async Task<ResultData<DistributorRate>> ConfirmRate([FromBody] SearchRateDto entity)
        {
            return await _IHotelApiService.ConfirmRate(entity.Distributor, entity.HotelId, entity.CheckinDate.Date, entity.CheckoutDate.Date, entity.RoomGuest, entity.RoomId, entity.RatePlanId, entity.CurrencyCode, Guid.NewGuid().ToString(), 60 * 1000);
        }

        public async Task<ResultData<string>> Reservation([FromBody] ReservationDto entity)
        {
            var disOrder = await _IOrderHotelService.GetDistributorOrder(entity.Distributor, entity.DistributorOrderId);
            if (disOrder != null)
            {
                return new ResultData<string> { Success = false, Code = ErrorCode.DataValidationFailed, Message = $"{entity.Distributor}-{entity.DistributorOrderId} 已存在", Data = disOrder.OrderId };
            }
            else
            {
                var hotel = await _IHotelService.GetHotel(entity.HotelId);
                var isChina = StringHelper.IsChina(hotel.CountryCode);
                var room = await _IHotelService.GetRoom(entity.RoomId);

                disOrder = new OrderHotelDistributor();
                disOrder.OrderId = "";
                disOrder.OrderStatus = OrderHotelStatus.Pending;
                disOrder.Distributor = entity.Distributor;
                disOrder.DistributorOrderId = entity.DistributorOrderId;
                disOrder.DistributorOrderStatus = DistributorOrderStatus.Confirmed;
                disOrder.HotelId = entity.HotelId;
                disOrder.HotelName = hotel.HotelNameEn.Enclosed(hotel.HotelNameCn);
                if (!isChina)
                    disOrder.HotelAddress = hotel.HotelAddressEn;
                else
                    disOrder.HotelAddress = hotel.HotelAddressCn;

                disOrder.HotelCountryName = hotel.CountryName;
                disOrder.HotelCityName = hotel.CityName;
                disOrder.HotelConfirmNo = "";
                disOrder.RoomId = entity.RoomId;
                if (room != null)
                {
                    disOrder.RoomName = room.RoomNameEn;
                }
                else
                {
                    if (!string.IsNullOrEmpty(entity.DisRate.RoomNameEn))
                        disOrder.RoomName = entity.DisRate.RoomNameEn.Enclosed(entity.DisRate.RoomNameCn);
                    else
                        disOrder.RoomName = entity.DisRate.SupplierRate.RoomName;
                }
                disOrder.RateplanId = entity.RatePlanId;
                disOrder.RoomCount = entity.RoomGuest.Count;
                disOrder.Checkin = entity.CheckinDate;
                disOrder.Checkout = entity.CheckoutDate;
                disOrder.GuestRoomJson = JsonConvert.SerializeObject(entity.RoomGuest);
                disOrder.ContactName = entity.ContactName;
                disOrder.ContactPhone = entity.ContactPhone;
                disOrder.ContactEmail = entity.ContactEmail;
                disOrder.MealType = entity.DisRate.MealType;
                disOrder.MealCount = entity.DisRate.MealCount;
                disOrder.FreeCancelTime = DateTimeHelper.GetFreeCancellationTime(entity.CheckinDate.Date, entity.DisRate.FreeCancellationTimeLimit);
                disOrder.GuestNote = entity.GuestRequest;
                disOrder.Currency = entity.Price.Currency;
                disOrder.Price = entity.Price.Amount;
                disOrder.CreatedTime = DateTime.Now;
                disOrder.UpdatedTime = DateTime.Now;
                var orderId = await _IOrderHotelService.InsertDistributorOrder(disOrder);

                await _IUpdateLogService.Add(new UpdateLog
                {
                    LogType = UpdateLogType.Order,
                    LogSubType = "NewOrder",
                    LogText = $"新建订单: {entity.Distributor}-{entity.DistributorOrderId}",
                    BusinessId = orderId,
                    UpdatedBy = UserId,
                    UpdatedByName = UserName,
                    UpdatedTime = DateTime.Now,
                });
            }

            var resultData = await _IHotelApiService.Reservation(entity.Distributor, entity.HotelId, entity.CheckinDate.Date, entity.CheckoutDate.Date, entity.RoomGuest, entity.RoomId, entity.RatePlanId, entity.DistributorOrderId, disOrder.OrderId, entity.Price, entity.GuestRequest, 60 * 1000, UserId, UserName);
            if (!resultData.Success)
                return new ResultData<string> { Success = false, Code = resultData.Code, Data = disOrder.OrderId, Message = $"预订失败: {resultData.Message}" };

            return new ResultData<string> { Success = true, Data = disOrder.OrderId, Message = "预订成功" };
        }

        public async Task<ResultData<string>> CancelSupplierOrder([FromBody] CancelSupplierOrderDto entity)
        {
            await _IUpdateLogService.Add(new UpdateLog
            {
                LogType = UpdateLogType.Order,
                LogSubType = "CancelSupOrder",
                LogText = $"取消订单: {entity.LogText}",
                BusinessId = entity.OrderId,
                UpdatedBy = UserId,
                UpdatedByName = UserName,
                UpdatedTime = DateTime.Now,
            });

            var resultData = await _IHotelApiService.CancelSupplierOrder(entity.Supplier, entity.SupplierOrderId, entity.OrderId, entity.SupplierExtrasJson, 60 * 1000, UserId, UserName);
            if (!resultData.Success)
                return new ResultData<string> { Success = false, Code = resultData.Code, Message = $"预订失败: {resultData.Message}" };

            return new ResultData<string> { Success = true, Message = "取消成功" };
        }
    }
}
